import Vue from 'vue'
import store from '@/store'

/**
 * Action 权限指令
 * 指令用法：
 *  - 在需要控制 action 级别权限的组件上使用 v-action:[method] , 如下：
 *    <i-button v-action:add >添加用户</a-button>    用户有add权限即可操作
 *    <a-button v-action:edit|delete>删除用户</a-button>    用户有edit或delete权限即可操作
 *    <a v-action:edit&delete @click="edit(record)">修改</a>    用户有edit且有delete权限才可操作
 *
 *  - 当前用户没有权限时，组件上使用了该指令则会被隐藏
 *  - 当后台权限跟 pro 提供的模式不同时，只需要针对这里的权限过滤进行修改即可
 *
 *  @see https://github.com/sendya/ant-design-pro-vue/pull/53
 */
const action = Vue.directive('action', {
  inserted: function (el, binding, vnode) {
    let actionNames = []
    let logicType = '|'
    const arg = binding.arg || binding.value
    if (arg) {
      if (arg.indexOf('|') > -1) {
        actionNames = arg.split('|')
        logicType = '|'
      } else if (arg.indexOf('&')) {
        actionNames = arg.split('&')
        logicType = '&'
      } else {
        actionNames = [arg]
      }
    }
    const actions = store.getters.actions
    const elVal = vnode.context.$route.meta.permissionId
    const permissionId = (elVal instanceof String && [elVal]) || elVal
    actions &&
      actions.forEach(a => {
        if (permissionId && !permissionId.includes(a.permissionId)) {
          el.style.display = 'none!important'
          return
        }
        if (logicType === '|') {
          if (a.actionList && !isContainOne(a.actionList, actionNames)) {
            (el.parentNode && el.parentNode.removeChild(el)) || (el.style.display = 'none!important')
          }
        } else {
          if (a.actionList && !isContainEvery(a.actionList, actionNames)) {
            (el.parentNode && el.parentNode.removeChild(el)) || (el.style.display = 'none!important')
          }
        }
      })
  }
})

export default action

/**
 * childArr中所有元素是否都存在于parentArr
 * @param {*} parentArr
 * @param {*} childArr
 */
function isContainEvery (parentArr, childArr) {
  for (let i = childArr.length - 1; i >= 0; i--) {
    if (!parentArr.includes(childArr[i])) {
      return false
    }
  }
  return true
}

/**
 * childArr中是否有至少一个元素存在于parentArr
 * @param {*} parentArr
 * @param {*} childArr
 */
function isContainOne (parentArr, childArr) {
  for (let i = childArr.length - 1; i >= 0; i--) {
    if (parentArr.includes(childArr[i])) {
      return true
    }
  }
  return false
}
